home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d7 / dbbs.arc / DBBS.SLT < prev    next >
Text File  |  1990-09-08  |  36KB  |  1,100 lines

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. //   D B B S . S L T
  4. //
  5. //   Copyright (C) 1988 PTel and Colin Sampaleanu
  6. //
  7. //   This is a Host Mode for Telix, written as a script file.
  8. //   To configure Host Mode parameters such as passwords, run the 'HCONFIG'
  9. //   script. That script is run automatically if the Host Mode ocnfiguration
  10. //   file 'HOST.CNF' is missing.
  11. //
  12. //   This script will only work with Hayes compatible modems, but may be
  13. //   modified for operation with othe rmodems.
  14. //
  15. //////////////////////////////////////////////////////////////////////////////
  16.  
  17. // Revised by Jon Fleming to use individual
  18. //     passwords, let anyone with level 3 access get at the shell or shut
  19. //     down host mode, and not display the shell option on the menu to those
  20. //     who don't have the access level to use it.
  21. // Revised By Dennis Seaton, made about 1000 little changes such as:
  22. //     Real menus!, Messages To sysop, Sysop can see what the user
  23. //     is doing in dos, More files can be displayed, just made it
  24. //     look 60% better by doing little things, no real programing.
  25. //
  26. // Parameters which can be configured
  27.  
  28. str password[16],                                  //caller's password
  29.     host_downloads[64],                 // where users may download from
  30.     host_uploads[64];                   // where uploaded files go
  31. int direct_connect = 0;
  32.  
  33. str current_caller[31],                 // storage of current caller's name
  34.     conn300[] = "CONNECT^M",            // modem result messages for bauds
  35.     conn1200[] = "CONNECT 1200",
  36.     conn2400[] = "CONNECT 2400",
  37.     conn9600[] = "CONNECT 9600",
  38.     conn19200[] = "CONNECT 19200";
  39. int finished_caller,                    // set to TRUE when must return to top
  40.     local_mode,                         // set to TRUE when local test mode
  41.     access_level,                       // access level of current caller
  42.     we_care_about_carrier = 1,                 // TRUE if should watch Carrier signal
  43.     already_connected = 0,
  44.     exit_requested = 0,                 // set to TRUE if Sysop has pressed Esc
  45.     connection_lost = 0,                // set to TRUE when carrier lost
  46.     kill_user = 0,                      // set to TRUE when user must be purged
  47.     min_user_name = 2;                      // Minimum length of a user name
  48.  
  49. int old_scr_chk_key,                    // storage for some system variables
  50.     old_cisb_auto,                      // which we have to modify and put
  51.     old_zmod_auto,                      // back to what they were when done
  52.     old_sound;
  53. str old_down_dir[64],
  54.     old_up_dir[64];
  55.  
  56. //////////////////////////////////////////////////////////////////////////////
  57. //////////////////////////////////////////////////////////////////////////////
  58.  
  59. main() {
  60.  
  61.    int c;
  62.  
  63.    clear_scr();
  64.  
  65.    if (read_host_config_file() == -1) {
  66.        prints("Unable to read HOST2.CNF...");
  67.        prints("Running DCONFIG, the Host Mode configuration script.^M^J");
  68.        call("DCONFIG");
  69.        if (read_host_config_file() == -1) {
  70.            prints("Still unable to read HOST2.CNF. Aborting Host Mode.^M^J");
  71.            return -1;
  72.        }
  73.    }
  74.  
  75.    if (!check_directories()) {
  76.        prints("Either the upload or download directory as defined in the HOST2.CNF file");
  77.        prints("doesn't exist. Either create the missing directory with the DOS 'MKDIR'");
  78.        prints("command, or run the DCONFIG script to redefine what directories to use.");
  79.        prints("Aborting Host Mode.");
  80.        return -1;
  81.    }
  82.  
  83.    old_scr_chk_key = _scr_chk_key;
  84.    _scr_chk_key = 0;
  85.    old_cisb_auto = _cisb_auto;
  86.    _cisb_auto = 0;
  87.    old_zmod_auto = _zmod_auto;
  88.    _zmod_auto = 0;
  89.    old_sound = _sound_on;
  90.    _sound_on = 0;
  91.    old_down_dir = _down_dir;
  92.    _down_dir = host_uploads;   // these are reversed because we are now the Host
  93.    old_up_dir = _up_dir;
  94.    _up_dir = host_downloads;   // these are reversed because we are now the Host
  95.  
  96.    usagelog("B:DBBS.LOG");
  97.  
  98.    if (direct_connect)
  99.        we_care_about_carrier = 0;
  100.    else
  101.        we_care_about_carrier = 1;
  102.  
  103.    if (!direct_connect && carrier())
  104.        already_connected = 1;
  105.  
  106.    if (!direct_connect && !already_connected) {
  107.        prints("Initializing modem");
  108.        cputs_tr(_auto_ans_str);
  109.    }
  110.  
  111.    while (1) {
  112.        finished_caller = kill_user = 0;
  113.  
  114.        if (direct_connect)
  115.            we_care_about_carrier = 0;
  116.        else
  117.            we_care_about_carrier = 1;
  118.  
  119.        if (!direct_connect) {
  120.            prints("^M^JDBBS: Waiting for sameone to call...");
  121.            prints("(Press Esc to exit, or 'L' for local test mode).^M^J");
  122.  
  123.            do {
  124.                if (carrier()) {
  125.                    local_mode = 0;
  126.                    break;
  127.                }
  128.  
  129.                c = inkey();
  130.                if (c) {
  131.                    if (c == 27) {
  132.                        exit_requested = 1;
  133.                        break;
  134.                    }
  135.                    else if (c == 'l' || c == 'L') {            // local test mode
  136.                        prints("Local test mode entered");
  137.                        local_mode = 1;
  138.                        we_care_about_carrier = 0;
  139.                    }
  140.                }
  141.            }
  142.            while (toupper(c) != 'L');
  143.        }
  144.  
  145.        if (!exit_requested) {
  146.            host_send("^G^LDBBS Version 1.1   -   By Dennis Seaton^G^M^J^M^J");
  147.            prints("* Incoming call. Press Esc to exit, or END to terminate user *");
  148.            _sound_on=1;
  149.            tone(500, 10);
  150.            tone(900, 10);
  151.            tone(500, 10);
  152.            tone(900, 10);
  153.            tone(500, 10);
  154.            tone(900, 10);
  155.            tone(500, 10);
  156.            do_one_caller();
  157.            if ((connection_lost || kill_user) && we_care_about_carrier && carrier())
  158.                hangup();             // make sure nobody sneaks in
  159.        }
  160.        already_connected = 0;
  161.        if (exit_requested) {
  162.            if (!carrier() && !direct_connect)
  163.                cputs_tr(_mdm_init_str);
  164.            _scr_chk_key = old_scr_chk_key;
  165.            _cisb_auto = old_cisb_auto;
  166.            _zmod_auto = old_zmod_auto;
  167.            _sound_on = old_sound;
  168.            _down_dir = old_down_dir;
  169.            _up_dir = old_up_dir;
  170.            prints("^M^JHost mode script finished.");
  171.            usagelog("B:DBBS.LOG");
  172.            return 1;
  173.        }
  174.    }
  175. }
  176. //////////////////////////////////////////////////////////////////////////////
  177.  
  178. do_one_caller() {
  179.  
  180.    str strn[80], fname[64], temporary[1];
  181.    str stuff[78];
  182.    int option, status, c, i, i2;
  183.  
  184.    access_level = 1;
  185.  
  186.    if (already_connected)
  187.        prints("Already Connected!");
  188.    else if (we_care_about_carrier) {
  189.        if (!determine_baud())
  190.            ;                       // do something else here if this is a problem
  191.    }
  192.  
  193.    delay(10);
  194.    type_file("B:FIRST.MSG");
  195.  
  196.    flushbuf();
  197.    while (1) {
  198.        host_send("Please Enter Your Alias -> ");
  199.        host_input_strn(current_caller, 30, 0);
  200.        host_send("^M^J");
  201.  
  202.        if (finished_caller)
  203.            return;
  204.  
  205.        if (strlen(current_caller) >= min_user_name) {
  206.            host_send ("^"");
  207.            host_send (current_caller);
  208.            host_send ("^", correct? (Y/N) -> ");
  209.            host_input_strn (temporary, 30, 0);
  210.            host_send ("^M^J");
  211.  
  212.            if (strcmpi (temporary, "y") == 0)
  213.                break;
  214.        }
  215.        else
  216.            host_send ("Too Short!^G^M^J");
  217.    }
  218.  
  219.    if (access_level = ask_for_pass(3)) {
  220.        ustamp("Logon by ", 1, 0);
  221.        ustamp(current_caller, 0, 1);
  222.    }
  223.    else {
  224.        host_send("^GGoodbye! Dont Call Back Dirt Bag^G^M^J");
  225.        if (we_care_about_carrier) {
  226.            delay(10);
  227.            hangup();
  228.        }
  229.        ustamp(" Failed logon attempt by ", 1, 0);
  230.        ustamp(current_caller, 0, 1);
  231.        return;
  232.    }
  233.  
  234.    type_file("B:Bulletin.msg");
  235.    host_send("- More -");
  236.    host_input_strn(stuff,1,0);
  237.    while (1) {
  238.        if (finished_caller)
  239.            return;
  240.  
  241.        type_file("B:MENU.MSG");                 // Normal Menu
  242.        host_send("                                   -> ");
  243.        host_input_strn(strn, 1, 0);
  244.        option = toupper(subchr(strn, 0));
  245.        host_send("^M^J");
  246.  
  247.        if (option == 'R') {                 // Files directory
  248.            if (access_level >= 2) {
  249.                host_send("^LRaw Files Directory^M^J");
  250.                host_send("===================^M^J^M^J");
  251.                host_send("Enter filespec or Return for *.* -> ");
  252.                host_input_strn(fname, 64, 0);
  253.                host_send("^M^J");
  254.  
  255.                if (just_filename(fname)) {
  256.                    strn = host_downloads;
  257.                    strcat(strn, fname);
  258.                }
  259.                else
  260.                strn = fname;
  261.            }
  262.            else {
  263.                strn = host_downloads;
  264.                strcat(strn, "*.*");
  265.            }
  266.  
  267.            if (local_mode)
  268.                show_directory(strn, 0, we_care_about_carrier);
  269.            else
  270.                show_directory(strn, 1, we_care_about_carrier);
  271.  
  272.        host_send("^M^J");
  273.        }
  274.  
  275.        else if (option == 'T') {           // Type a file
  276.            host_send("^LType File^M^J");
  277.            host_send("=========^M^J^M^J");
  278.            host_send("Type what file -> ");
  279.            host_input_strn(strn, 64, 0);
  280.            host_send("^M^J");
  281.            if (access_level == 1)             // if access 1, name and ext only
  282.                fnstrip(strn, 3, fname);
  283.            else
  284.                fname = strn;
  285.  
  286.            if (just_filename(fname)) {
  287.                strn = host_downloads;
  288.                strcat(strn, fname);
  289.                fname = strn;
  290.            }
  291.  
  292.            if (!filefind(fname, 0, strn)) {
  293.                host_send("^GUnable to find ");
  294.                host_send(fname);
  295.                continue;
  296.            }
  297.  
  298.            type_file(fname);
  299.        }
  300.  
  301.        else if (option == 'L') {           // Goodbye (Hang-up)
  302.            type_file("B:LAST.MSG");
  303.            ustamp("User logged off.", 1, 1);
  304.            if (we_care_about_carrier) {
  305.                delay(10);
  306.                hangup();
  307.            }
  308.            return;
  309.        }
  310.  
  311.        else if (option == 'Y') {           // Chat mode
  312.            host_send("^LChat Mode^M^J");
  313.            host_send("=========^M^J^M^J");
  314.            host_send("Paging Sysop, You may leave a message if he is not in.^M^J");
  315.            c = 0;
  316.            _sound_on = 1;
  317.            for (i = 4; i && !c; --i) {
  318.                if (we_care_about_carrier && !carrier()) {
  319.                    prints("^M^JConnection has been lost, call terminated.^M^J");
  320.                    connection_lost = 1;
  321.                    finished_caller = 1;
  322.                    break;
  323.                }
  324.                cputc('^G');
  325.                tone(475, 10);
  326.                tone(925, 10);
  327.                tone(475, 10);
  328.                tone(925, 10);
  329.                tone(475, 10);
  330.                tone(925, 10);
  331.                for (i2 = 30; i2 && (c = inkey()) == 0; --i2)
  332.                    delay(1);
  333.            }
  334.            _sound_on = 0;
  335.            if (finished_caller)
  336.                continue;
  337.            if (c != ' ' || !c) {
  338.                host_send("^LSorry The Sysop Is Unavaliable! (Or Doesnt wanna talk!)^M^J^M^J");
  339.                host_send("But Leave Him A Short Message (5 Lines)^M^J");
  340.                ustamp("^G ** Message To Sysop ** ",0,1);
  341.                host_send("^M^J1>");
  342.                host_input_strn(stuff,78,0);
  343.                ustamp(stuff,0,1);
  344.                host_send("^M^J2>");
  345.                host_input_strn(stuff,78,0);
  346.                ustamp(stuff,0,1);
  347.                host_send("^M^J3>");
  348.                host_input_strn(stuff,78,0);
  349.                ustamp(stuff,0,1);
  350.                host_send("^M^J4>");
  351.                host_input_strn(stuff,78,0);
  352.                ustamp(stuff,0,1);
  353.                host_send("^M^J^G5>");
  354.                host_input_strn(stuff,78,0);
  355.                ustamp(stuff,0,1);
  356.                continue;
  357.            }
  358.            host_send("^M^JHi, how can I help ya?^M^J^M^J");
  359.            chatmode(1);
  360.        }
  361.       else if (option == 'F')    // Files List
  362.        {
  363.       type_file ("B:FILES.BBS");
  364.       host_send("- More -");
  365.       host_input_strn(stuff,1,0);
  366.       }
  367.       else if (option == 'B')
  368.       {
  369.       type_file ("B:BULLETIN.MSG");
  370.       host_send("- More -");
  371.       host_input_strn(stuff,1,0);
  372.       }
  373.       else if (option == 'I')
  374.       {
  375.       type_file("B:BBSNUM.LST");
  376.       host_send("- More -");
  377.       host_input_strn(stuff,1,0);
  378.       }
  379.       else if (option == '*')
  380.       {
  381.       type_file("B:DBBS.LOG");
  382.       }
  383.       else if (option == 'N')
  384.       {
  385.       type_file("B:newuser.ifo");
  386.       host_send("- More -");
  387.       host_input_strn(stuff,1,0);
  388.       }
  389.       else if (option == 'E')
  390.       {
  391.       type_file ("B:extra.ifo");
  392.       host_send("- More -");
  393.       host_input_strn(stuff,1,0);
  394.       }
  395.        else if (option == 'U') {           // User upload
  396.            if (! (option = host_get_prot()))
  397.                continue;
  398.  
  399.            status = 1;
  400.            if (option == 'T' || option == 'M' || option == 'S' ||
  401.                    option == 'Y' || option == 'Z' || option == 'E') {
  402.                send_transfer_msg();
  403.                status = receive(option, "");
  404.            }
  405.            else {
  406.                host_send("Upload what file -> ");
  407.                host_input_strn(strn, 48, 0);
  408.                host_send("^M^J");
  409.                if (!strn)
  410.                    continue;
  411.                if (access_level == 1)             // if access 1, name and ext only
  412.                    fnstrip(strn, 3, fname);
  413.                else
  414.                    fname = strn;
  415.  
  416.                if (just_filename(fname)) {
  417.                    strn = host_uploads;
  418.                    strcat(strn, fname);
  419.                    fname = strn;
  420.                }
  421.  
  422.                if (filefind(fname, 23, strn))
  423.                    host_send("Thanks, but I have that already!^G^M^J");
  424.                else {
  425.                    send_transfer_msg();
  426.                    status = receive(option, fname);
  427.                }
  428.            }
  429.            if (status == -2)                        // Carrier lost
  430.                connection_lost = finished_caller = 1;
  431.            else if (status == -1)
  432.                host_send("^G-> One or more files not received! <-^M^J");
  433.        }
  434.  
  435.        else if (option == 'D') {           // User download
  436.            if (! (option = host_get_prot()))
  437.                continue;
  438.            host_send("^M^JAnother download leech eh?^M^J");
  439.            host_send("Download what file(s) -> ");
  440.            host_input_strn(strn, 48, 0);
  441.            host_send("^M^J");
  442.            if (!strn)
  443.                continue;
  444.            if (access_level == 1)      // if level 1, keep only name & ext
  445.                fnstrip(strn, 3, fname);
  446.            else
  447.                fname = strn;
  448.  
  449.            if (just_filename(fname)) {
  450.                strn = host_downloads;
  451.                strcat(strn, fname);
  452.                fname = strn;
  453.            }
  454.  
  455.            if (!filefind(fname, 0, strn)) {
  456.                host_send("^G* I dont have that file! *^M^J");
  457.                continue;
  458.            }
  459.  
  460.            status = 1;
  461.            send_transfer_msg();
  462.            status = send(option, fname);
  463.            if (status == -2)                        // Carrier lost
  464.                connection_lost = finished_caller = 1;
  465.            else if (status == -1)
  466.                host_send("^G * One or more files not received! *^M^J");
  467.        }
  468.  
  469.        else if (option == 'S') {           // Remote shell
  470.            if (get_port() != 1 && get_port() != 2) {
  471.                host_send("Remote Shell not supported on this comm port due to DOS limits!^M^J");
  472.                continue;
  473.            }
  474.  
  475.            if (access_level == 3) {            // Need access level 3 to shell
  476.                host_send("^LDos Shell^M^J");
  477.                host_send("=========^M^J^M^J");
  478.                host_send(" - DO NOT delete ANYTHING ^M^J");
  479.                host_send(" - Type EXIT to return to DBBS ^M^J");
  480.                host_send(" - Accessing the C: drive will crash the BBS, DONT!^M^J^M^J");
  481.                if (get_baud() == 300)
  482.                    delay(10);
  483.  
  484.                strn = "GATE1";     // THE GATEWAY DRIVER IS NEEDED CHANGE GATE1 TO STRN
  485.                setchr("GATE1", 3, get_port() + '0'); // AND TAKE OUT QUOTES ON THIS LINE
  486.                                                   // TO MAKE IT WORK WITH OUT GATEWAY
  487.                if (!local_mode)
  488.                    if (redirect_dos("GATE1") == -1)    // redirect DOS input and output
  489.                        continue;
  490.  
  491.                dos("", 0);                    // actually call the shell
  492.  
  493.                    if (!local_mode)
  494.                        redirect_dos("");         // very important to put things back to norm
  495.            }
  496.            else {
  497.                host_send ("^G^G * Your Access Level Is Too Low *^M^J");
  498.            }
  499.        }
  500.  
  501.        else if (option == '^Z') {            // Shut down Host Mode
  502.            if (access_level == 3) {
  503.                host_send("Shutting down DBBS.  Goodbye!^M^J");
  504.                if (we_care_about_carrier)
  505.                    hangup();
  506.                ustamp("User shut down Host Mode.", 1, 1);
  507.                finished_caller = 1;
  508.                exit_requested = 1;
  509.            }
  510.            else {
  511.                host_send ("^G^G * Your Access Level Is Too Low *^M^J");
  512.            }
  513.        }
  514.    }
  515. }
  516.  
  517. //////////////////////////////////////////////////////////////////////////////
  518.  
  519. host_get_prot() {
  520.  
  521.    str prot[1];
  522.    host_send("^L            File Transfer^M^J");
  523.    host_send("            =============^M^J^M^J");
  524.    host_send("    [Z]modem          [S]ealink^M^J");
  525.    host_send("    [X]modem          [1]k-Xmodem^M^J");
  526.    host_send("    [G]-1k-Xmodem     [Y]modem^M^J");
  527.    host_send("^M^J    Which protocol -> ");
  528.    host_input_strn(prot, 1, 0);
  529.    host_send("^M^J");
  530.  
  531.    if (strposi("MSX1GYEZ", prot, 0) == -1)     // if illegal prot
  532.        prot = "";                                 // return 0
  533.  
  534.    return (toupper(subchr(prot, 0)));
  535.  
  536. }
  537.  
  538. //////////////////////////////////////////////////////////////////////////////
  539.  
  540. send_transfer_msg() {
  541.  
  542.    host_send("-> Ready to transfer file(s)... Slam on Ctrl-X to abort <-^M^J");
  543. }
  544.  
  545. //////////////////////////////////////////////////////////////////////////////
  546. // Determine the baud rate once a Carrier Detect Signal has been detected
  547. // Since no characters were read, the 'CONNECT' string should still be
  548. // in the receive buffer.
  549.  
  550. determine_baud() {
  551.  
  552.    int t3, t12, t24, t96, t192;
  553.    int tmark, stat;
  554.    int new_baud = 0;
  555.  
  556.    printsc("Determining baud... ");
  557.  
  558.    track_free(0);                // clear all existing tracks
  559.  
  560.    t3 = track(conn300, 0);       // check for connect strings
  561.    t12 = track(conn1200, 0);
  562.    t24 = track(conn2400, 0);
  563.    t96 = track(conn9600, 0);
  564.    t192 = track(conn19200, 0);
  565.  
  566.    tmark = timer_start(30);      // wait up to 3 seconds for string
  567.  
  568.    while (!time_up(tmark)) {
  569.        if (!carrier()) {
  570.            track_free(0);            // clear all existing tracks
  571.            return 0;
  572.        }
  573.  
  574.    if (cinp_cnt())
  575.        track_addchr(cgetc());
  576.  
  577.    stat = track_hit(0);
  578.    if (stat == 0)
  579.        continue;
  580.  
  581.    if (stat == t3)
  582.        new_baud = 300;
  583.    else if (stat == t24)
  584.        new_baud = 2400;
  585.    else if (stat == t96)
  586.        new_baud = 9600;
  587.    else if (stat == t192)
  588.        new_baud = 19200;
  589.    else
  590.        new_baud = 1200;
  591.  
  592.    break;                      // have baud rate, get out
  593.    }
  594.  
  595.    if (!new_baud) {               // time-up without CONNECT string
  596.        prints("Failed!");
  597.        track_free(0);              // clear all existing tracks
  598.        return 0;
  599.    }
  600.  
  601.    printn(new_baud);
  602.    prints("");
  603.    set_cparams(new_baud, get_parity(), get_datab(), get_stopb());
  604.  
  605.    track_free(0);                // clear all existing tracks
  606.    return 1;                     // indicate success
  607.  
  608. }
  609.  
  610. //////////////////////////////////////////////////////////////////////////////
  611.  
  612. type_file(str fname) {
  613.  
  614.    int f, control_z_loc;
  615.    str buf[100];
  616.    int ichar, lines_sent = 0;
  617.  
  618.    if (not (f = fopen(fname, "r")))
  619.        return -1;
  620.  
  621.    host_send("^M^J");
  622.  
  623.    while (1) {
  624.        if (we_care_about_carrier) {
  625.            if (!carrier()) {
  626.                connection_lost = 1;
  627.                finished_caller = 1;
  628.                fclose(f);
  629.                return 0;
  630.            }
  631.        }
  632.  
  633.        if (fgets(buf, 80, f) == -1) {
  634.            fclose(f);
  635.            return 1;
  636.        }
  637.  
  638.        if ((control_z_loc = strpos (buf, "^Z", 0)) >= 0) {
  639.            if (control_z_loc == 0) {
  640.                fclose (f);
  641.                return 1;
  642.            }
  643.            else {
  644.                setchr (buf, control_z_loc, 0);
  645.            }
  646.        }
  647.  
  648.        host_send(buf);
  649.        host_send("^M^J");
  650.        ++lines_sent;
  651.  
  652.        if (lines_sent >= 22222) {
  653.            lines_sent = 0;
  654.            host_send("- More -");
  655.            host_input(0);
  656.  
  657.            if (finished_caller) {        // if user inactivity
  658.                fclose(f);
  659.                return 0;
  660.            }
  661.  
  662.            host_send("^H ^H^H ^H^H ^H^H ^H^H ^H^H ^H^H ^H");
  663.        }
  664.  
  665.        while (cinp_cnt()) {
  666.            ichar = cgetc();
  667.            if (ichar == '^C' || ichar == '^K') {
  668.                host_send("^M^J");
  669.                fclose(f);
  670.                return 1;
  671.            }
  672.        }
  673.    }
  674. }
  675.  
  676. //////////////////////////////////////////////////////////////////////////////
  677.  
  678. host_send(str outstr) {
  679.  
  680.    printsc(outstr);
  681.    if (!local_mode)
  682.        cputs(outstr);
  683.  
  684. }
  685.  
  686. //////////////////////////////////////////////////////////////////////////////
  687.  
  688. host_send_c(int chr) {
  689.  
  690.    printc(chr);
  691.    if (!local_mode)
  692.        cputc(chr);
  693.  
  694. }
  695.  
  696. //////////////////////////////////////////////////////////////////////////////
  697.  
  698. host_input_strn(str buf, int maximum, int echo_asterisk) {
  699.  
  700. //Rev 11/25/88 by Jon Fleming to echo a string of asterisks if
  701. //     "echo_asterisk" is non-zero, echo the input string if "echo_asterisk"
  702. //     is zero.
  703.  
  704.    int i = 0, key;
  705.  
  706.    while (1) {
  707.        key = host_input(echo_asterisk);
  708.        if (!key) {                // timeout or user disconnect
  709.            setchr(buf, 0, 0);      // set string to empty
  710.            return 0;               // indicate there is a problem
  711.        }
  712.  
  713.        if (key == '^M')
  714.            break;
  715.        if (key == 127 || key == 8) {
  716.            if (i) {
  717.                --i;
  718.                host_send_c(key);
  719.            }
  720.            continue;
  721.        }
  722.        if (i < maximum) {
  723.            setchr(buf, i, key);
  724.            i = i + 1;
  725.        }
  726.        else
  727.            i = i + 1;
  728.    }
  729.  
  730.    if (i > maximum)
  731.        i = maximum;
  732.  
  733.    setchr(buf, i, '^0');
  734.  
  735.    if (subchr(buf, 0))
  736.        return 1;
  737.    else
  738.        return 0;
  739.  
  740. }
  741.  
  742. //////////////////////////////////////////////////////////////////////////////
  743.  
  744. host_input(int echo_asterisk) {
  745.  
  746. // Rev 11/25 88 by Jon Fleming to echo asterisk if "echo_asterisk" is
  747. //     non-zero, to echo the input character if "echo_asterisk" is zero.
  748.  
  749.    int c, t;
  750.  
  751.    t = timer_start(3000);         // 4 minutes inactivity allowed
  752.  
  753.    while (1) {
  754.        if (time_up(t) && !direct_connect) {
  755.            host_send("^L^M^J^M^J^G^G^GInactivity period too long! Goodbye!^M^J");
  756.            if (we_care_about_carrier)
  757.                hangup();
  758.            finished_caller = 1;
  759.            kill_user = 1;
  760.            return 0;
  761.        }
  762.  
  763.        if (we_care_about_carrier)
  764.            if (!carrier()) {
  765.                prints("^M^JConnection has been lost, call terminated.^M^J");
  766.                connection_lost = 1;
  767.                finished_caller = 1;
  768.            return 0;
  769.            }
  770.  
  771.        if ((c = inkey()) != 0) {
  772.            if (c == 27) {              // ESC key, sysop wants to exit
  773.                finished_caller = 1;
  774.                exit_requested = 1;
  775.                return 0;
  776.            }
  777.            else if (c == 0x4f00) {     // END key, temrinate user
  778.                prints("^M^J* Jerk terminated! *");
  779.                ustamp(" Jerk User terminated!", 1, 1);
  780.                if (we_care_about_carrier)
  781.                hangup();
  782.  
  783.                finished_caller = 1;
  784.                kill_user = 1;
  785.                return 0;
  786.            }
  787.  
  788.            else if (c <= 255) {
  789.                if (c != 8 && c != 127) {
  790.                    if ( (echo_asterisk) && (c != 13) ) {
  791.                        host_send_c ('*');
  792.                    }
  793.                    else {
  794.                        host_send_c(c);
  795.                    }
  796.                }
  797.                return c;
  798.            }
  799.        }
  800.  
  801.        if (!local_mode)
  802.            if (cinp_cnt()) {
  803.                c = cgetc();
  804.                if (c != 8 && c != 127) {
  805.                    if ( (echo_asterisk) && (c != 13) ) {
  806.                    host_send_c ('*');
  807.                    }
  808.                else {
  809.                    host_send_c(c);
  810.                }
  811.            }
  812.            return c;
  813.        }
  814.    }
  815. }
  816.  
  817. //////////////////////////////////////////////////////////////////////////////
  818.  
  819.  
  820. // This routine maintains an ASCII file in the Telix files directory called
  821. //     PASSWORD.TLX.  The format for each line is:
  822.  
  823. //     name;password;access_level  (optional comment)
  824.  
  825. //     The name, password, and acces_level fields MUST be seperated by
  826. //     semicolons
  827.  
  828. // The routine searches the file for a line on which the "name" field
  829. //     matches the global variable "current_caller"  (not case sensitive).
  830.  
  831. // If a match is found, and the user can type a password that matches
  832. //     the "password" field (not case sensitive), the routine returns
  833. //     the integer "access_level".
  834.  
  835. // If no match is found, the user is given an opportunity to reigister
  836. //     (at access level 1).
  837.  
  838. // If the user registers, the file is updated with the new user name,
  839. //     password, and access level (1), the routine returns 1.
  840.  
  841. // If the user does not register, or if the user cannot match the password
  842. //     in the file in "maxtries",  or if the user registers and cannot match
  843. //     the password he/she chose in "maxtries", the routine retuns 0.
  844.  
  845. ask_for_pass(int maxtries) {
  846.    str password_file[64], line_from_file[80], password_from_file[16],
  847.            name_from_file[31], temporary[16], typed_password[16];
  848.  
  849.    int password_file_handle, field_length, field_start,
  850.            found_password = 0, access_from_file, counter = 0,
  851.            file_ends_in_control_z = 0, line_number = 0;
  852.  
  853.                                            // Build password file name
  854.    password_file = _telix_dir;
  855.    strcat (password_file, "PASSWORD.TLX");
  856.                                            // Try to open password file
  857.    if (password_file_handle = fopen (password_file, "r")) {
  858.                                            // Read next line from file.
  859.        while (fgets (line_from_file, 64, password_file_handle) != -1) {
  860.                                            // Check for ^Z termination
  861.            if (line_from_file == "^Z") {
  862.                file_ends_in_control_z = 1;
  863.                break;
  864.            }
  865.            line_number = line_number + 1;
  866.                                            // If line is long enough . . .
  867.            if (strlen (line_from_file) >= min_user_name+4) {
  868.                                            // Get length of name
  869.                if ( (field_length = strchr (line_from_file, 0, ';')) > 0) {
  870.                                            // Get name
  871.                    substr (line_from_file, 0, field_length, name_from_file);
  872.                                            // If name matches . . . .
  873.                    if (strcmpi (name_from_file, current_caller) == 0) {
  874.                                            // Get password
  875.                        field_start = field_length + 1;
  876.                        if ( (field_length = strchr (line_from_file, field_start, ';') - field_start) > 0) {
  877.                            substr (line_from_file, field_start, field_length, password_from_file);
  878.                                            // Get access level
  879.                            field_start = field_start + field_length + 1;
  880.                            substr (line_from_file, field_start, 1, temporary);
  881.                            access_from_file = stoi (temporary);
  882.                                            // Set flag that we got an old user
  883.                            found_password = 1;
  884.                            break;
  885.                        }
  886.                        else {
  887.                            password_file_error (line_number, line_from_file, "no second semicolon");
  888.                        }
  889.                    }
  890.                }
  891.                else {
  892.                    password_file_error (line_number, line_from_file, "no first semicolon");
  893.                }
  894.            }
  895.            else {
  896.                password_file_error (line_number, line_from_file, "line too short");
  897.            }
  898.        }
  899.        fclose (password_file_handle);
  900.    }
  901.  
  902.    if (found_password) {
  903.                                            // Password is on file; ask for it
  904.        host_send ("Password -> ");
  905.        for (counter = 1; counter <= maxtries; counter = counter + 1) {
  906.            host_input_strn (typed_password, 16, 1);
  907.                                            // If a match
  908.            if (strcmpi (typed_password, password_from_file) == 0) {
  909.                host_send ("^M^J");
  910.                return (access_from_file);
  911.            }
  912.            if (counter <maxtries) {
  913.                host_send ("^M^J^G WRONG PASSWORD! Try again.^M^J");
  914.                host_send ("Password -> ");
  915.            }
  916.            else {
  917.                host_send ("^L^M^J^G^G^G^GTOO MANY ATTEMPTS BYE!^M^J");
  918.            }
  919.        }
  920.    }
  921.                                            // Password is not on file
  922.    else {
  923.                                            // Offer chance to register
  924.        host_send ("^L^M^J Hello ^"");
  925.        host_send (current_caller);
  926.        host_send ("^" , You are not found in the user file.^J^M^J^M");
  927.        host_send ("Would you like to register with this great bbs (Y/N) -> ");
  928.        host_input_strn (temporary, 1, 0);
  929.        host_send ("^M^J");
  930.                                            // If user doesn't want to register
  931.        if (not ((temporary == "Y") || (temporary == "y"))) {
  932.            return (0);
  933.        }
  934.                                            // If user wants to register
  935.        host_send("^LRegistration Questionaire^M^J");
  936.        host_send("=========================^M^J^M^J");
  937.        host_send ("Pick a password (16 characters maximum) -> ");
  938.        host_input_strn (password_from_file, 16, 1);
  939.                                            // Make sure password is right
  940.        host_send ("^M^JRe-Enter Your Password To Verify -> ");
  941.        for (counter = 1; counter <= maxtries; counter = counter + 1) {
  942.            host_input_strn (typed_password, 16, 1);
  943.                                            // If all is ok
  944.            if (strcmpi (typed_password, password_from_file) == 0) {
  945.                                            // Build new line for password file
  946.                line_from_file = current_caller;
  947.                strcat (line_from_file, ";");
  948.                strcat (line_from_file, password_from_file);
  949.                strcat (line_from_file, ";1 **NEW USER** ");
  950.                date (curtime(), temporary);
  951.                strcat (line_from_file, temporary);
  952.                                            // Open password file for appending
  953.                password_file_handle = fopen (password_file, "a+");
  954.                if (file_ends_in_control_z) {
  955.                    fseek (password_file_handle, -1, 2);
  956.                }
  957.                                            // Now we can write the line
  958.                fwrite (line_from_file, strlen (line_from_file), password_file_handle);
  959.                fwrite ("^M^J", 2, password_file_handle);
  960.                fclose (password_file_handle);
  961.                host_send ("^M^J");
  962.                                            // Return access level
  963.                return (1);
  964.            }
  965.            if (counter < maxtries){
  966.                host_send ("^M^J^GWrong!  Try again. ");
  967.            }
  968.            else {
  969.                host_send ("^M^J^G^G^GMaximum amount of tries exceeded!^M^J");
  970.            }
  971.        }
  972.    }
  973.    return (0);
  974. }
  975.  
  976. //////////////////////////////////////////////////////////////////////////////
  977. // A routine to print an error message to the local screen when something
  978. //     is wrong with the password file
  979.  
  980. password_file_error (int line_number, str line, str error_specifier) {
  981.  
  982.    str line_number_string[4];
  983.  
  984.    itos (line_number, line_number_string);
  985.  
  986.    prints ("");
  987.    printsc ("Bad line ");
  988.    printsc (line_number_string);
  989.    prints (" in password file:");
  990.    printsc ("   ^"");
  991.    printsc (line);
  992.    prints ("^"");
  993.    prints (error_specifier);
  994.  
  995.    return (1);
  996. }
  997.  
  998. //////////////////////////////////////////////////////////////////////////////
  999.  
  1000. //Rev 11/25/88 by Jon Fleming to not read the lines from the old host mode
  1001. //  configuration file that are no longer applcable.
  1002.  
  1003. read_host_config_file() {
  1004.  
  1005.    str config_file_name[80], buffer [32];
  1006.    int config_file_handle;
  1007.  
  1008.    config_file_name = _telix_dir;
  1009.    strcat(config_file_name, "HOST2.CNF");
  1010.  
  1011.  
  1012.    if (not (config_file_handle = fopen(config_file_name, "r"))) {
  1013.        printsc("Can't open ");
  1014.        prints(config_file_name);
  1015.        return -1;
  1016.    }
  1017.  
  1018.    if (fgets(host_downloads, 80, config_file_handle) == -1) {
  1019.        fclose(config_file_handle);
  1020.        return -1;
  1021.    }
  1022.  
  1023.    if (fgets(host_uploads, 80, config_file_handle) == -1) {
  1024.        fclose(config_file_handle);
  1025.        return -1;
  1026.    }
  1027.  
  1028.    if (fgets(buffer, 80, config_file_handle) == -1) {
  1029.        fclose(config_file_handle);
  1030.        return -1;
  1031.    }
  1032.    direct_connect = (toupper(subchr(buffer, 0)) == 'D');
  1033.  
  1034.    fclose(config_file_handle);
  1035.    return 1;
  1036.  
  1037. }
  1038.  
  1039. //////////////////////////////////////////////////////////////////////////////
  1040.  
  1041. check_directories() {
  1042.  
  1043.    str s[80];
  1044.    int i, a;
  1045.  
  1046.    // first remove trailing slashes
  1047.  
  1048.    s = host_uploads;
  1049.    i = strlen(s);
  1050.    if (i > 0)
  1051.        if (subchr(s, i - 1) == '\' || subchr(s, i - 1) == '/')
  1052.            setchr(s, i - 1, 0);
  1053.    if (s && !(strlen(s) == 2 && subchr(s, 1) == ':')) {
  1054.        a = fileattr(s);
  1055.        if (a == -1 || !(a & 16))
  1056.            return 0;                  // not a directory or doesn't exist
  1057.    }
  1058.  
  1059.    s = host_downloads;
  1060.    i = strlen(s);
  1061.    if (i > 0)
  1062.        if (subchr(s, i - 1) == '\' || subchr(s, i - 1) == '/')
  1063.            setchr(s, i - 1, 0);
  1064.    if (s && !(strlen(s) == 2 && subchr(s, 1) == ':')) {
  1065.        a = fileattr(s);
  1066.        if (a == -1 || !(a & 16))
  1067.            return 0;                  // not a directory or doesn't exist
  1068.    }
  1069.  
  1070.    return 1;
  1071.  
  1072. }
  1073.  
  1074. //////////////////////////////////////////////////////////////////////////////
  1075. // returns TRUE if passed filespec is just a filename. Also handles the
  1076. // forward slash as a path separator.
  1077.  
  1078. just_filename(str filespec) {
  1079.  
  1080.    int slash, space;
  1081.  
  1082.    if (strpos(filespec, ":", 0) != -1)
  1083.        return 0;
  1084.    if (strpos(filespec, "\", 0) != -1)
  1085.        return 0;
  1086.    if ((slash = strpos(filespec, "/")) == -1)
  1087.        return 1;
  1088.  
  1089.    space = strpos(filespec, " ");
  1090.    if (space == -1)
  1091.        return 0;
  1092.    if (space < slash)
  1093.        return 1;
  1094.  
  1095.    return 0;
  1096.  
  1097. }
  1098.  
  1099. //////////////////////////////////////////////////////////////////////////////
  1100.